#Finds the vertical, horizontal and diagonal Field of View and the size of the frame at the focal distance

from math import atan, ceil, degrees, radians, sqrt, tan
#atan is Python.math's version of arctan, degrees converts radians to degrees, and sqrt returns the square root of a float

def calculateRectFOV (sensorWidth, sensorHeight, focalLength, focalDist):

    #Convert focalLength to float, catch invalid input.
    try:
        focalLength = float(focalLength)
    except ValueError:
        return "Invalid Input (focalLength)"
    #Convert focalDist to float, catch invalid input.
    try:
        focalDist = float(focalDist) * 1000
    except ValueError:
        return "Invalid Input (focalDist)"


    #Calculates the vertical Field of View of the shot
    vertFOV = degrees(2 * atan(sensorHeight/(focalLength * 2)))
    #Calculates the horizontal Field of View of the shot
    horiFOV = degrees(2 * atan(sensorWidth/(focalLength * 2)))
    #Calculates the diagonal Field of View of the shot
    diagFOV = degrees(2 * atan(sqrt((sensorHeight * sensorHeight) + (sensorWidth * sensorWidth))/(focalLength * 2)))
    #Finds the height of the image at the focal point
    frameHeight = 2 * (focalDist * tan(radians(vertFOV) / 2))
    #Finds the width of the image at the focal point
    frameWidth = 2 * (focalDist * tan(radians(horiFOV) / 2))
    #Finds the diagonal length of the image at the focal point
    diagFrameLength = 2 * (focalDist * tan(radians(diagFOV) / 2))

    #Return raw results. Distances in millimeters.
    #results = [vertFOV, horiFOV, diagFOV, frameHeight, frameWidth, diagFrameLength]

    #formatting for output
    vertFOVOutput = ceil(vertFOV)
    horiFOVOutput = ceil(horiFOV)
    diagFOVOutput = ceil(diagFOV)
    #more formatting & conversion to meters
    frameHeightOutput = ceil(frameHeight) / 1000
    frameWidthOutput = ceil(frameWidth) / 1000
    diagFrameLengthOutput = ceil(diagFrameLength) / 1000

    #preparing results for output to GUI level
    results = "Horizontal FOV = " + str(horiFOVOutput) +" degrees\nFrame width at the focal point is " + str(frameWidthOutput) + " meters.\nVertical FOV = " + str(vertFOVOutput) + " degrees\nFrame height at the focal point is " + str(frameHeightOutput) + " meters.\nDiagonal FOV = " + str(diagFOVOutput) + " degrees\nDiagonally, the frame is " + str(diagFrameLengthOutput) + " meters at the focal point."

    return results

#Valid Input
#theresults = calculateRectFOV (36.0, 24.0, "50", "2")
#print theresults
#Invalid Input
#theresults = calculateRectFOV (36.0, 24.0, "praise", "2")
#print theresults
#theresults = calculateRectFOV (36.0, 24.0, "50", "him")
#print theresults